home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
emulation
/
c64gfx
/
src
/
foxtoppm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
6KB
|
268 lines
/************************************************************************\
* C64 printfox to portable pixmap converter 2-May-93 *
* By Pasi 'Albert' Ojala (c) 1991-1998 *
* albert@cs.tut.fi albert@cc.tut.fi *
* *
* 22-Jan-95 TABsize=8, cleaning up *
* *
* PageFox format by Nicolas Welte 06-Jul-1998 *
* welte@chemie.uni-konstanz.de *
* *
* 21-Jul-98 Reformatting and cleaning up of the source code *
* Also, reduced memory consumption and added '-m' flag -Pasi *
* *
\************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char UBYTE;
char *vers="\0$VER: foxtoppm 1.3 22-Jul-98\n";
#define TABLESIZE 65000
static UBYTE gfxmem[TABLESIZE];
static int width, height, mode;
static int flags = 0;
void Convert(char *name);
#define F_MULTI (1<<0)
#define F_ERROR (1<<7)
int main(int argc, char *argv[]) {
int i, pointer = 0, repeats, c, size = 0;
char *inFile = NULL, *outFile = NULL;
FILE *inFp;
for (i=1; i<argc; i++) {
if (argv[i][0]=='-') {
for (c=1; argv[i][c]; c++) {
switch (argv[i][c]) {
case 'm':
flags |= F_MULTI;
break;
default:
flags |= F_ERROR;
}
}
} else {
if (!inFile) {
inFile = argv[i];
} else if (!outFile) {
outFile = argv[i];
} else {
flags |= F_ERROR;
}
}
}
if ((flags & F_ERROR)) {
fprintf(stderr, "\n%s", vers+7);
fprintf(stderr, "Usage: %s [-m] [printfoxfile] [ppmfile]\n", argv[0]);
fprintf(stderr, " m - force multicolor mode\n");
exit(10);
return EXIT_FAILURE;
}
if (inFile) {
inFp = fopen(inFile, "rb");
if (!inFp) {
fprintf(stderr, "Could not open %s for reading\n", inFile);
return EXIT_FAILURE;
}
} else {
inFp = stdin;
}
mode = fgetc(inFp);
size++;
if (mode == EOF) {
fprintf(stderr,
"Unexpected EOF while reading file type\n");
if (inFp != stdin)
fclose(inFp);
return EXIT_FAILURE;
}
switch (mode) {
case 0x50:
height = fgetc(inFp);
width = fgetc(inFp);
size += 2;
if (height == EOF || width == EOF) {
fprintf(stderr,
"Unexpected EOF while reading picture size\n");
if (inFp != stdin)
fclose(inFp);
return EXIT_FAILURE;
}
c = 2 + height*4; /* skip ID and outline info */
size += 2 + height*4;
while (c--) {
(void)fgetc(inFp);
}
fprintf(stderr, "PG (short RLE) %d(w) x %d(h)\n", width, height);
break;
case 0x47:
width = 80;
height = 50;
fprintf(stderr, "GB (long RLE) %d(w) x %d(h)\n", width, height);
break;
case 0x42:
width = 40;
height = 25;
fprintf(stderr, "BS %s(single screen) %d(w) x %d(h)\n",
(flags & F_MULTI)?"multicolor ":"",
width, height);
break;
case 0x01:
width = 40;
height = 25;
fprintf(stderr, "Uncompressed %s%d(w) x %d(h)\n",
(flags & F_MULTI)?"multicolor ":"",
width, height);
break;
default:
fprintf(stderr, "ID not recognized (%d)\n", mode);
if (inFp != stdin)
fclose(inFp);
return EXIT_FAILURE;
}
if (mode==0x01) {
/* Uncompressed */
for (i=0; i<8000; i++) {
gfxmem[i] = (c = fgetc(inFp));
if (c == EOF) {
fprintf(stderr,
"Unexpected EOF while reading graphics data\n");
break;
}
}
if (inFp != stdin)
fclose(inFp);
Convert(outFile);
return 0;
}
/* 0x50 PG(short RLE) 0x47 GB(long RLE), 0x42 small (printfox) */
while (pointer < TABLESIZE) {
c = fgetc(inFp);
if (c == EOF)
break;
size++;
if (c == 0x9b) {
/* Repeat */
c = fgetc(inFp);
if (c == EOF)
break;
size++;
repeats = c;
if (mode == 0x50) {
if (repeats == 0)
repeats = 256;
} else {
c = fgetc(inFp);
if (c == EOF)
break;
size++;
repeats += c*256;
}
c = fgetc(inFp);
if (c == EOF)
break;
size++;
while (repeats--) {
if (pointer<0 || pointer>=TABLESIZE) {
fprintf(stderr,
"Pixel table overrun: %d\n",
pointer);
break;
}
gfxmem[pointer++] = c;
}
} else {
gfxmem[pointer++] = c;
}
}
c = fgetc(inFp);
if (c != EOF) {
fprintf(stderr, "Extra bytes in the input file\n");
}
if (inFp != stdin)
fclose(inFp);
fprintf(stderr, "%d bytes compressed, %d uncompressed\n",
size, pointer);
Convert(outFile);
return 0;
}
void Convert(char *name) {
int x,y,pos,z;
static const UBYTE bitmask[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
static const UBYTE bitmask2[4] = {0xc0,0x30,0x0c,0x03};
FILE *handle;
UBYTE *buffer = malloc(3*width*8);
if (!buffer) {
fprintf(stderr, "Could not allocate %d bytes\n", 3*width*8);
return;
}
fprintf(stderr,"Converting picture\n");
if (name) {
handle = fopen(name, "wb");
} else {
handle = stdout;
}
if (!handle) {
fprintf(stderr, "Could not open %s for writing\n", name);
free(buffer);
return;
}
if ((flags & F_MULTI))
fprintf(handle,"P6\n%d %d\n255\n", width*4, height*8);
else
fprintf(handle,"P6\n%d %d\n255\n", width*8, height*8);
if ((flags & F_MULTI)) {
for (y=0; y<height*8; y++) {
for (x=0; x<width*4; x++) {
pos = (y%8)+(x/4)*8+(y/8)*320; /* grafix memory byte */
z = (3-((gfxmem[pos] & bitmask2[x%4])>>((3-x%4)*2)))*255/3;
buffer[3*x] = z;
buffer[3*x+1] = z;
buffer[3*x+2] = z;
}
fwrite(buffer, width*4, 3, handle);
}
} else {
for (y=0; y<height*8; y++) {
for (x=0; x<width*8; x++) {
pos = (y%8)+(x/8)*8+(y/8)*width*8; /* grafix memory byte */
if ((gfxmem[pos] & bitmask[x%8])) {
buffer[3*x] = 0;
buffer[3*x+1] = 0;
buffer[3*x+2] = 0;
} else {
buffer[3*x] = 255;
buffer[3*x+1] = 255;
buffer[3*x+2] = 255;
}
}
fwrite(buffer, width*8, 3, handle);
}
}
if (handle != stdout)
fclose(handle);
free(buffer);
}